﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Spider.Entity;
using Spider.Parser;
using System.Data;
using System.Windows.Forms;
using System.Collections;

namespace Spider.Core
{
    public delegate void ParserCompletedEventHandler(object sender, ParserEventArgs e);

    public class ParserEngin
    {
        public event ParserCompletedEventHandler ParserCompleted;

        private List<EmailInfo> _email = new List<EmailInfo>();

        private Queue queue = new Queue();

        private Queue myQueue = null;

        private object o = new object();

        //需要处理的uri总数
        private int _count = 0;

        private Dictionary<string, ParserConfig> _config = null;

        //每个线程解析的URI数量
        private double _iCount = 1;

        private Main _mainForm;
        public Main MainForm
        {
            set { _mainForm = value; }
        }


        public ParserEngin()
        {
            ConfigManager cm = new ConfigManager();
            _config = cm.GetParserConfig();
        }

        public void DoParse()
        {
            List<UriInfo> uris = GetUris();
            _count = uris.Count;

            foreach (var item in uris)
                queue.Enqueue(item);
            //包装队列，使其同步
            myQueue = Queue.Synchronized(queue);

            Thread[] thread = new Thread[100];
            ThreadStart threadStart = new ThreadStart(ParseTask);
            for (int i = 0; i < 100; i++)
            {
                thread[i] = new Thread(threadStart);
                thread[i].Start();

                //Thread.Sleep(1000);
            }
        }

        //解析任务：执行具体的解析操作
        //private void ParseTask(int i, List<KeyValuePair<string, string>> uris)
        private void ParseTask()
        {
            while (myQueue.Count > 0)
            {
                try
                {
                    UriInfo uri = (UriInfo)myQueue.Dequeue();
                    Type t = Type.GetType(_config[uri.Parser].Parser);
                    ParserBase parser = (ParserBase)Activator.CreateInstance(t);
                    parser.Parser(uri.Uri, uri.City, _config[uri.Parser], ref _email);
                    _mainForm.label2.Text = myQueue.Count.ToString();
                    Decrease();
                }
                catch (Exception)
                {

                    Decrease();
                }
            }
        }

        public List<UriInfo> GetUris()
        {
            string query = "Select * From Uri where state=0 ";
            return SQLHelper.ExecuteDataset(query).Tables[0].Rows
                .Cast<DataRow>()
                .Select<DataRow, UriInfo>(
                    p => new UriInfo() { Uri = p["uri"].ToString(), City = p["city"].ToString(), Parser = p["parser"].ToString() })
                .ToList();
        }

        private void OnParserCompleted(ParserEventArgs e)
        {
            if (ParserCompleted != null)
                ParserCompleted(this, e);
        }

        //减少_count : 判断是否触发事件
        private void Decrease()
        {
            lock (o)
            {
                _count--;

                _mainForm.label2.Text = _count.ToString();
                //触发完成事件
                if (_count <= 0)
                {
                    ParserEventArgs e = new ParserEventArgs(_email);
                    OnParserCompleted(e);
                }
            }
        }
    }

    public class ParserEventArgs : EventArgs
    {
        private List<EmailInfo> _email = null;

        public ParserEventArgs(List<EmailInfo> email)
        {
            _email = email;
        }

        public List<EmailInfo> Email
        {
            get { return _email; }
        }
    }
}
